package com.gd.iot.energy.service.systemadmin.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.systemadmin.PricePOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.systemadmin.PricePO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.systemadmin.dto.PriceSaveDTO;
import com.gd.iot.energy.pojo.systemadmin.vo.EnumVO;
import com.gd.iot.energy.pojo.systemadmin.vo.PricePageVO;
import com.gd.iot.energy.pojo.systemadmin.vo.PriceVO;
import com.gd.iot.energy.service.systemadmin.PriceService;
import com.gd.iot.energy.util.CustomBeanUtils;
import com.gd.iot.energy.util.CustomColumnUtil;
import com.gd.iot.energy.util.CustomStrUtil;
import com.gd.iot.energy.util.EnergyTypeUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class PriceServiceImpl extends ServiceImpl<PricePOMapper, PricePO> implements PriceService {
    @Resource
    private PricePOMapper pricePOMapper;

    /**
     * 表头文件
     */
    private static final String INSTRUCTION_LIST_COLUMN_FILE_NAME = "systemadmin/price_list.column";

    @Override
    public List<PriceVO> getPriceVOs() {
        QueryWrapper<PricePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        List<PricePO> pricePOS = pricePOMapper.selectList(queryWrapper);
        List<PriceVO> priceVOS = new ArrayList<>(pricePOS.size());
        CustomBeanUtils.convertPojo(pricePOS, priceVOS, PriceVO.class);
        return priceVOS;
    }

    @Override
    public PageVO<PricePageVO> getPricePageVOs(Integer pageSize, Integer pageNo, String orderColumn, String orderType) {
        IPage<PricePO> page = new Page<>(pageNo, pageSize);
        QueryWrapper<PricePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            orderColumn = CustomStrUtil.humpToLine(orderColumn);
            queryWrapper.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        IPage<PricePO> pricePOIPage = pricePOMapper.selectPage(page, queryWrapper);
        PageVO<PricePageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNo);
        List<PricePageVO> treePageVOS = convertToPricePageVOList(pricePOIPage.getRecords(), pageSize, pageNo);
        pageVO.setData(treePageVOS);
        pageVO.setTotal(pricePOIPage.getTotal());
        pageVO.setPages(pricePOIPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(INSTRUCTION_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    /**
     * 对象转换
     *
     * @param records
     * @return
     */
    private List<PricePageVO> convertToPricePageVOList(List<PricePO> records, Integer pageSize, Integer pageNo) {
        List<PricePageVO> res = new ArrayList<>(records.size());
        PricePageVO instructionTreePageVO;

        int i = pageSize * (pageNo - 1) + 1;
        for (PricePO record : records) {
            instructionTreePageVO = new PricePageVO();
            instructionTreePageVO.setSerialNum(i);
            instructionTreePageVO.setId(record.getId());
            instructionTreePageVO.setPriceName(record.getPriceName());
            instructionTreePageVO.setStartdate(record.getStartdate());
            instructionTreePageVO.setFlatPrice(record.getFlatPrice());
            instructionTreePageVO.setStateName(SystemConsts.EnabledState.getValuenameByValue(record.getState()));

            res.add(instructionTreePageVO);
            i++;
        }
        return res;
    }


    @Override
    public Long add(PriceSaveDTO priceSaveDTO) {
        if (StrUtil.isBlank(priceSaveDTO.getPriceName()) ||
                StrUtil.isBlank(priceSaveDTO.getStartdate())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        PricePO pricePO = new PricePO();
        pricePO.setCompanyId(0L);
        pricePO.setCreateDate(new Date());
        pricePO.setEnergyType(SystemConsts.EnergyTypeEnum.WATER.value);
        pricePO.setIsDel(SystemConsts.BooleanEnum.FALSE.value);
        pricePO.setModifyDate(new Date());
        pricePO.setOperatorId(1L);
        pricePO.setFlatPrice(priceSaveDTO.getFlatPrice());
        pricePO.setPriceName(priceSaveDTO.getPriceName());
        pricePO.setStartdate(priceSaveDTO.getStartdate());
        pricePO.setState(priceSaveDTO.getState());

        if (SystemConsts.LadderType.FLAT.value.equals(priceSaveDTO.getLadderType())) {
            pricePO.setLadderType(SystemConsts.LadderType.FLAT.value);
        } else {
            pricePO.setLadderDosage(priceSaveDTO.getLadderDosage());
            pricePO.setLadderType(SystemConsts.LadderType.LADDER.value);
        }

        if (!"1".equals(SystemConsts.EnergyTypeEnum.WATER.value.toString())) {
            pricePO.setTipPrice(priceSaveDTO.getFlatPrice());
            pricePO.setPeakPrice(priceSaveDTO.getFlatPrice());
            pricePO.setValleyPrice(priceSaveDTO.getFlatPrice());
        }

//        pricePO.setLadderBalanceDate();

        pricePOMapper.insert(pricePO);
        return pricePO.getId();
    }

    @Override
    public boolean update(PriceSaveDTO priceSaveDTO) {
        if (StrUtil.isBlank(priceSaveDTO.getPriceName()) ||
                StrUtil.isBlank(priceSaveDTO.getStartdate())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        PricePO pricePO = new PricePO();
        pricePO.setId(priceSaveDTO.getId());
        pricePO.setModifyDate(new Date());
        pricePO.setOperatorId(1L);
        pricePO.setFlatPrice(priceSaveDTO.getFlatPrice());
        pricePO.setPriceName(priceSaveDTO.getPriceName());
        pricePO.setStartdate(priceSaveDTO.getStartdate());
        pricePO.setState(priceSaveDTO.getState());

        if (SystemConsts.LadderType.FLAT.value.equals(priceSaveDTO.getLadderType())) {
            pricePO.setLadderType(SystemConsts.LadderType.FLAT.value);
        } else {
            pricePO.setLadderDosage(priceSaveDTO.getLadderDosage());
            pricePO.setLadderType(SystemConsts.LadderType.LADDER.value);
        }

        if (!"1".equals(SystemConsts.EnergyTypeEnum.WATER.value.toString())) {
            pricePO.setTipPrice(priceSaveDTO.getFlatPrice());
            pricePO.setPeakPrice(priceSaveDTO.getFlatPrice());
            pricePO.setValleyPrice(priceSaveDTO.getFlatPrice());
        }

//        pricePO.setLadderBalanceDate();

        pricePOMapper.updateById(pricePO);
        return true;
    }

    @Override
    public boolean delete(List<Integer> ids) {
        if (CollUtil.isEmpty(ids)) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        //供应商表逻辑删除
        QueryWrapper<PricePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        PricePO pricePO = new PricePO();
        pricePO.setIsDel(SystemConsts.BooleanEnum.TRUE.value);
        int num = pricePOMapper.update(pricePO, queryWrapper);

        return num > 0;
    }

    @Override
    public PriceSaveDTO getPrice(Integer id) {
        PricePO pricePO = pricePOMapper.selectById(id);
        if (pricePO == null || SystemConsts.BooleanEnum.TRUE.value.equals(pricePO.getIsDel())) {
            throw new MyException(ResponseCode.RECORD_NOT_EXIST);
        }

        PriceSaveDTO priceSaveDTO = new PriceSaveDTO();
        priceSaveDTO.setId(pricePO.getId());
        priceSaveDTO.setPriceName(pricePO.getPriceName());
        priceSaveDTO.setStartdate(pricePO.getStartdate());
        priceSaveDTO.setFlatPrice(pricePO.getFlatPrice());
        priceSaveDTO.setState(pricePO.getState());
        priceSaveDTO.setLadderDosage(pricePO.getLadderDosage());
        priceSaveDTO.setLadderType(pricePO.getLadderType());

        return priceSaveDTO;
    }

    @Override
    public Map<String, List<EnumVO>> getEnums() {
        Map<String, List<EnumVO>> resultMap = new HashMap<>();

        List<EnumVO> enabledState = new ArrayList<>();
        for (SystemConsts.EnabledState value : SystemConsts.EnabledState.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            enabledState.add(vo);
        }

        List<EnumVO> ladder = new ArrayList<>();
        for (SystemConsts.LadderType value : SystemConsts.LadderType.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            ladder.add(vo);
        }

        resultMap.put("enabledState", enabledState);
        resultMap.put("ladder", ladder);
        return resultMap;
    }
}
